import 'dart:async';
import 'dart:convert';
import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_application_1/components/load_more/load_more.dart';
import 'package:flutter_application_1/components/loading_tip/loading_tip.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter_application_1/Global.dart';
import 'package:lpinyin/lpinyin.dart';
import 'package:flutter_application_1/components/hide_scroll_shadow/hide_scroll_shadow.dart';
import 'package:flutter_application_1/components/tap_mask/tap_mask.dart';
import 'package:flutter_application_1/utils/utils.dart';
import 'search_row.dart';

const Duration _duration = Duration(milliseconds: 200);

Future<T?> showCityListSelector<T>({
  required BuildContext context,
}) {
  return showGeneralDialog<T>(
    context: context,
    barrierDismissible: true,
    barrierLabel: '',
    transitionDuration: _duration,
    transitionBuilder: (
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
      Widget child,
    ) {
      return FractionalTranslation(
        translation: Offset(1 - animation.value, 0),
        transformHitTests: true,
        child: child,
      );
    },
    pageBuilder: (
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
    ) {
      return CityListSelector();
    },
  );
}

class _CityListSelectorSaveData {
  static List list = [];
}

class CityListSelector extends StatefulWidget {
  final Color? primaryColor;

  CityListSelector({
    this.primaryColor,
  });

  @override
  State<StatefulWidget> createState() => CityListSelectorState();
}

class CityListSelectorState extends State<CityListSelector> {
  List<CityItem> cityItemList = [];

  Map<String, List<CityItem>> cityMap = {
    'A': [],
    'B': [],
    'C': [],
    'D': [],
    'E': [],
    'F': [],
    'G': [],
    'H': [],
    'I': [],
    'J': [],
    'K': [],
    'L': [],
    'M': [],
    'N': [],
    'O': [],
    'P': [],
    'Q': [],
    'R': [],
    'S': [],
    'T': [],
    'U': [],
    'V': [],
    'W': [],
    'X': [],
    'Y': [],
    'Z': [],
    '#': [],
  };

  List cityList = [];

  ScrollController _scrollController = ScrollController();

  List<CityItem> _searchList = [];

  late StreamSubscription _keyboardListener;

  bool _isShowLetterList = true;

  // 处理数据
  void _dealData(List _cityJsonList) {
    cityItemList = _cityJsonList
        .map(
          (json) => CityItem.fromJson(json),
        )
        .toList();
    cityItemList.forEach((CityItem city) {
      String pinyin = PinyinHelper.getPinyinE(
        city.name ?? '',
        defPinyin: '#',
        format: PinyinFormat.WITHOUT_TONE,
      ).substring(0, 1).toUpperCase();
      cityMap[pinyin]!.add(city);
    });

    cityMap.forEach(
      (key, value) {
        GlobalKey<CityGroupState> globalKey = GlobalKey<CityGroupState>();
        Map city = {
          'label': key,
          'list': value,
          'key': globalKey,
          'height': 0,
        };

        cityList.add(city);

        WidgetsBinding.instance!.addPostFrameCallback((_) {
          Rect rect = WidgetUtil.getWidgetBounds(globalKey.currentContext!);
          city['height'] = rect.height;
        });
      },
    );

    setState(() {});
  }

  // 初始数据
  Future<void> _initData() async {
    if (_CityListSelectorSaveData.list.length > 0) {
      _dealData(_CityListSelectorSaveData.list);
    } else {
      rootBundle.loadString('assets/cities.json').then((value) {
        List _cityJsonList = json.decode(value);

        _dealData(_cityJsonList);

        _CityListSelectorSaveData.list = _cityJsonList;
      });
    }
  }

  // 取消焦点
  void loseFocus() {
    FocusScope.of(context).requestFocus(FocusNode());
  }

  // 搜索
  void _search(String keyword) {
    debounce(() {
      setState(() {
        if (keyword.isNotEmpty) {
          _searchList = cityItemList.where((CityItem cityItem) {
            return (cityItem.name ?? '').indexOf(keyword) != -1;
          }).toList();
        } else {
          _searchList = [];
        }
      });
    }, 200, false)();
  }

  // 滚动到某个字母开头的城市列表
  void _scrollByLabel(String label) {
    double scrollHeight = 0;
    cityList.firstWhere((city) {
      String _label = city['label'];
      List<CityItem> list = city['list'];
      double height = city['height'];

      // 找到列表
      if (_label == label && list.length > 0) {
        _scrollController.jumpTo(scrollHeight);
        return true;
      }
      scrollHeight += height;
      return false;
    }, orElse: () {
      Fluttertoast.showToast(msg: '没有$label开头的城市');
    });
  }

  // 点击选择
  void _onChanged(String label) {
    loseFocus();
    Navigator.pop(context, label);
  }

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance!.addPostFrameCallback((_) {
      Future.delayed(Duration(milliseconds: 350), () {
        _initData();
      });
    });

    _keyboardListener =
        KeyboardVisibilityController().onChange.listen((bool isShow) {
      setState(() {
        _isShowLetterList = !isShow;

        if (!isShow) {
          loseFocus();
        }
      });
    });
  }

  @override
  void dispose() {
    super.dispose();

    _keyboardListener.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('选择城市'),
        centerTitle: true,
        elevation: 0,
        backgroundColor: widget.primaryColor ?? Global.Primary_Color,
      ),
      body: Stack(
        children: <Widget>[
          // 城市列表
          HideScrollShadow(
            child: CustomScrollView(
              controller: _scrollController,
              slivers: <Widget>[
                SearchRow(
                  onChanged: _search,
                ),
                ...List.generate(cityList.length, (index) {
                  Map cityGroup = cityList[index];
                  String label = cityGroup['label'];
                  List<CityItem> list = cityGroup['list'];
                  GlobalKey<CityGroupState> key = cityGroup['key'];

                  return SliverToBoxAdapter(
                    child: CityGroup(
                      label: label,
                      list: list,
                      key: key,
                      onTap: (String cityName) {
                        _onChanged(cityName);
                      },
                    ),
                  );
                }),
                SliverToBoxAdapter(
                  child: cityList.length > 0
                      ? SizedBox()
                      : LoadMore(
                          status: LoadMoreStatus.Loading,
                        ),
                ),
              ],
            ),
          ),
          // 字母列表
          _isShowLetterList
              ? Positioned(
                  top: 0,
                  bottom: 0,
                  right: 0,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: List.generate(cityList.length, (index) {
                      Map cityGroup = cityList[index];
                      String label = cityGroup['label'];
                      return GestureDetector(
                        behavior: HitTestBehavior.opaque,
                        onTap: () {
                          _scrollByLabel(label);
                        },
                        child: Container(
                          width: 40 * Utils.rpx + 5,
                          height: 40 * Utils.rpx,
                          padding: EdgeInsets.only(right: 5),
                          alignment: Alignment.center,
                          child: Text(
                            label,
                            style: TextStyle(
                              color: Color.fromRGBO(170, 170, 170, 1),
                              fontSize: 30 * Utils.rpx,
                            ),
                          ),
                        ),
                      );
                    }),
                  ),
                )
              : SizedBox(),
          // 搜索结果
          _searchList.length > 0
              ? Positioned(
                  top: kToolbarHeight,
                  bottom: 0,
                  left: 0,
                  right: 0,
                  child: Container(
                      color: Colors.white,
                      child: SingleChildScrollView(
                        child: Column(
                          children: List.generate(
                            _searchList.length,
                            (index) {
                              CityItem cityItem = _searchList[index];
                              return CityRow(
                                label: cityItem.name ?? '',
                                onTap: () {
                                  _onChanged(cityItem.name ?? '');
                                },
                              );
                            },
                          ),
                        ),
                      )),
                )
              : SizedBox(),
        ],
      ),
    );
  }
}

// 城市分类
class CityGroup extends StatefulWidget {
  final String label;
  final List<CityItem> list;
  final Function(String) onTap;

  CityGroup({
    Key? key,
    required this.label,
    required this.list,
    required this.onTap,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => CityGroupState();
}

class CityGroupState extends State<CityGroup> {
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        widget.list.length > 0
            ? Container(
                color: Color.fromRGBO(235, 236, 238, 1),
                padding: EdgeInsets.all(10),
                child: Text(
                  widget.label,
                  style: TextStyle(
                    color: Color.fromRGBO(170, 170, 170, 1),
                  ),
                ),
              )
            : SizedBox(height: 0),
        ...List.generate(
          widget.list.length,
          (index) {
            CityItem cityItem = widget.list[index];
            return CityRow(
              label: cityItem.name ?? '',
              onTap: () {
                widget.onTap(cityItem.name ?? '');
              },
            );
          },
        ),
      ],
    );
  }
}

class CityRow extends StatelessWidget {
  final String label;
  final Function onTap;

  CityRow({
    required this.label,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return TapMask(
      onTap: () {
        if (onTap != null) {
          onTap();
        }
      },
      borderRadius: 0,
      child: Container(
        width: Utils.width,
        padding: EdgeInsets.symmetric(
          vertical: 15,
          horizontal: 10,
        ),
        decoration: BoxDecoration(
          border: Border(
            bottom: BorderSide(
              color: Color.fromRGBO(235, 236, 238, 1),
              width: 1,
            ),
          ),
        ),
        child: Text(label),
      ),
    );
  }
}

// 城市实体类
class CityItem {
  String? code;
  String? name;
  String? parent_code;

  CityItem({
    this.code,
    this.name,
    this.parent_code,
  });

  CityItem.fromJson(Map<String, dynamic> json) {
    code = json['code'];
    name = json['name'];
    parent_code = json['parent_code'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['code'] = this.code;
    data['name'] = this.name;
    data['parent_code'] = this.parent_code;
    return data;
  }
}
